#!/usr/bin/env python
# coding=utf-8

if __name__ == '__main__':
    """ for file debug"""
    import sys,os
    sys.path.insert(0,os.path.join( os.getcwd(), '..' ))

import vavava.util
from vavava.base import LogAdapter
from vavava.httpclient import HttpClient
from vavava.workqueue import Work
from .types_track import TrackItem
from . import table_tracking
from . import fetcher_track_security_code
import re

class TrackFetcher:
    """ check item tracking info
    """
    fetch_format=r'http://auspost.com.au/track/track.html?id=%s'
    def __init__(self, item, conn, debug_level=0, soc_timeout=10,
                 log=None, name="<?>", proxy=None):
        self.log = LogAdapter(log)
        self._item = item
        self.debug_level = debug_level
        self.timeout = soc_timeout
        self._conn = conn
        self._tracking = None
        self.name = name
        self.track_dict={}
        self.fetch_url = TrackFetcher.fetch_format % item
        self.client = HttpClient()
        self.proxy = proxy
        if self.proxy and self.proxy != "":
            self.client.AddProxy(self.proxy)
        self.client.req_timeout = self.timeout
        self._tracking = table_tracking.Tracking(self._conn, self.log)

    def Fetch(self):
        """ return true/false"""
        try:
            data = self.client.Get(self.fetch_url)
            text = data.decode('ISO-8859-1','ignore')
            reg_str=r'<a\s*name="emailNotification">[^<]*</a>[^<]*<table[^>]*>.*</table>'
            tag_table_text = vavava.util.reg_helper(text,reg_str)
            if tag_table_text is None or len(tag_table_text) == 0:
                # security code
                fetcher2 = fetcher_track_security_code.FetchTrack2(self._item,self.log)
                tag_table_text = fetcher2.get_data()
                if tag_table_text is None or len(data) == 0:
                    self._error_handle( "[%s]security code failed" % self._item )
                    return False
                else:
                    self.log.info("[%s] security code ok." % self._item )
            else:
                tag_table_text = tag_table_text[0]
            # got item info text
            # get tag tr
            reg_str=r'<\s*tr[^>]*>(?P<content>.*?)<\s*/\s*tr\s*>'
            tag_trs = vavava.util.reg_helper(tag_table_text,reg_str)
            if tag_trs is None or len(tag_trs) == 0:
                self._error_handle( "[%s]Failed to get tag_trs.\n%s" % (self._item, tag_table_text) )
                return False
            # get item info list from tags
            tag_trs = tag_trs[1:]  # avoid title row
            track_list=[]
            for tr in tag_trs:
                itemInfo=TrackItem.parse(self._item,tr)
                if itemInfo:
                    track_list.append(itemInfo)
                else:
                    self.log.warn("WRTrackInfo init failed:"+tr)
            # got item info
            for item_info in track_list:
                if not self.track_dict.get(item_info):
                    self.track_dict[item_info]=item_info
                    re = self._new_data(item_info)
                    if re == -1:
                        self.log.warn("[%s] Item info already in db, %s" % ( self.name, item_info ) )
                    elif re == 2:
                        self.log.info("[%s] Tracking ended for %s" % ( self.name, item_info ) )
                        break
            self.log.debug("[%s] Item info chk over." % self._item )
            return True
        except Exception as e:
            self._error_handle(str(e))
            return False

    @staticmethod
    def get_track_items_from_web():
        """
        get list from "http://fastrackexpress.com.au/test.php?LIST=POST"
        and return  ItemList
        """
        from vavava.httpclient import HttpClient
        import  re
        try:
            items = []
            client=HttpClient()
            html=client.Get(r"http://fastrackexpress.com.au/test.php?LIST=POST")
            htmlStr=html.decode('utf-8')
            reg_str=r'<td>(?P<id>[^<]*)</td>'
            reg=re.compile(reg_str,re.X)
            idList=reg.findall(htmlStr)
            item = idList[1:]
            return item
        except:
            return None

    def _new_data(self,item):
        """
        result_     1   now data stored
                    2   tracking ended
                   -1   already in db
        """
        self.log.info("[%s] Tracking New tracking info coming:%s,%s,%s,%s"%
                      (self._item,item.Name ,item.Description,item.Location,item.TrackTime))
        return self._tracking.sp_insert_new_item(
            item.Name,item.TrackTime,item.Description, item.Location)

    def _error_handle(self, e):
        if e:
            self.log.error("[%s] error happend:%s" % (self._item,e))
        if self._tracking:
            return self._tracking.sp_update_item_status(self._item)
        else:
            self.log.error("[%s] error happend: db access error at meantime..."
                           % self._item)

    def _dump_error(self,item_id,fetch_url,text="",e=None):
        SAVEPATH=r'ex-pages'
        """ save exception page"""
        from time import localtime,time
        import codecs,os
        if text is None or text == "":
            return
        t=localtime(time())
        t_str="%d%d%d%d%d%d"%(t.tm_year,t.tm_mon , t.tm_mday,
                              t.tm_hour, t.tm_min, t.tm_sec)
        filename=r'./%s/%s_%s.html'%(self.SAVEPATH,item_id,t_str)
        vavava.util.assure_path("./%s"%self.SAVEPATH)
        f=codecs.open(filename,"w",'utf-8')
        file_full_name=os.path.abspath(filename)
        if f:
            f.writelines('<!--' + fetch_url + '--!>'+os.linesep)
            f.write(text)
            f.close()
        self.log.error(r"page saved at %s"%file_full_name)

class TaskGenerator_ChkTrackingInfo(Work):
    def __init__(self,period,group,begin_time=None,
                 end_time=None,log=None,name="<?>",**awarg):
        Work.__init__(
            self,period=period,group=group,begin_time=begin_time,
            end_time=end_time,log=log,name=name,awarg=awarg
        )
        self.timeout_items_ = {}
        self.delivered_items_ = {}
        self.tracking_items_ = {}
        self.conn_ = self._work_param
        self.proxy = None
        if awarg:
            proxy = awarg.get("proxy")
            if proxy:
                self.proxy = awarg["proxy"]
        self.redo_counter = 10

    def do(self,worker=None):
        if not worker:
            self.log.error("[%s] Unknown parent,cannot add work for main task. "
                           % self._work_name )
            return
        if self.conn_ is None and self._work_param:
            self.conn_ = self._work_param
        elif self.conn_ is None and self._work_param is None:
            self.log.error("[%s] DBObj is Null." % self._work_name )
            return
        self.log.info("[%s] AddTrackWork begin. [redo=%d,work_done=%s]"
                      % (self._work_name,self.redo_counter, str(self._done)) )
        # get data from db
        tracking = table_tracking.Tracking(self.conn_,self.log)
        self.tracking_items_  = tracking.get_tracking_items()
        self.delivered_items_ = tracking.get_delivered_items()
        self.timeout_items_   = tracking.get_timeout_items()
        self.log.info("[%s] Get db data:[tracking_items_=%d,delivered_items_=%d,timeout_items_=%d]"
                  % (self._work_name,len(self.tracking_items_),len(self.delivered_items_),len(self.timeout_items_)) )
        # get items from web
        items_web = TrackFetcher.get_track_items_from_web()
        # process data
        new_items = []
        for item in items_web:
            if self.delivered_items_.get(item):
                continue
            if self.timeout_items_.get(item):
                continue
            if not self.delivered_items_.get(item):
                # new item
                self.log.info( "[%s] New item:%s" % (item,self._work_name) )
                new_items.append(item)
                self.delivered_items_[item] = ""
        else:
            self.log.warn("[%s] Get 0 item from web." % self._work_name )

        self.log.info("[%s] new_items_size=%d" % (self._work_name,len(new_items)) )

        # add to workshop
        for item in self.delivered_items_:
            # runtime works for item
            work = WorkChkTrackInfo(
                itemID=item, group=self.group_id, conn=self.conn_, log=self.log, proxy=self.proxy )
            worker._wq_parent.QueueWork(work=work)
            self.log.debug("[%s] Add tracking work to workshop. Item=%s"%(self._work_name,item))

        self.redo_counter -= 1
        if self.redo_counter > 0:
            self._done = False # need start again
        else:
            self._done = True # do not need start again

        self.log.info("[%s] AddTrackWork ended. [redo=%d,work_done=%s]"
                      % (self._work_name,self.redo_counter, str(self._done)) )

class WorkChkTrackInfo(Work):
    def __init__(self,itemID,group,conn,proxy=None,debug_level=0,soc_timeout=10,
                 begin_time=None,end_time=None,period=None,
                 log=None,name="TrackWork"):
        Work.__init__(self,period=period,group=group,
            begin_time=begin_time,end_time=end_time,log=log,name=name)
        self._work_param = conn
        self.fetcher = TrackFetcher(
            item = itemID,
            conn = self._work_param,
            debug_level = debug_level,
            soc_timeout = soc_timeout,
            log = log,
            name = name,
            proxy = proxy
        )

    def do(self,worker=None):
        self.fetcher.Fetch()

    def __hash__(self):
        return hash(self.fetcher._item)


if __name__ == '__main__':
    pass
